package com.drcoffee.drcoffeemall.service.impl;

import com.drcoffee.drcoffeemall.entry.*;
import com.drcoffee.drcoffeemall.mapper.AfterSaleMapper;
import com.drcoffee.drcoffeemall.mapper.OrderMapper;
import com.drcoffee.drcoffeemall.service.AfterSaleService;
import com.drcoffee.drcoffeemall.util.SendWxWorkUtil;
import com.drcoffee.drcoffeemall.util.PayRefundUtil;
import com.wechat.pay.java.service.refund.model.AmountReq;
import org.apache.ibatis.annotations.ResultMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class AfterSaleServiceImpl implements AfterSaleService {

    @Autowired
    AfterSaleMapper afterSaleMapper;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Autowired
    PayRefundUtil payRefundUtil;
    @Autowired
    SendWxWorkUtil sendWxWorkUtil;

    @Override
    public ResponseEntity<Map<String, Object>> getAfterSaleByStatus(Map<String, Object> paramMap) {
        System.out.println(paramMap);
        Map<String, Object> resultMap = new HashMap<>();
        List<Map<String, Object>> afterSaleByStatus = afterSaleMapper.getAfterSaleByStatus(paramMap);
        List<Map<String, Object>> newAfterSaleList = AfterSaleData2(afterSaleByStatus);
        resultMap.put("data", newAfterSaleList);
        return new ResponseEntity<>(resultMap, HttpStatus.OK);
    }


    @Scheduled(cron = "0 0 0 * * ?")
    public void timeOut(){
        List<AfterSale> afterSales = afterSaleMapper.allAfterSale();
        for (AfterSale afterSale : afterSales) {
            if (afterSale.getTime_out()!=null && !afterSale.getTime_out().equals("")
                    &&afterSale.getType()==2 && afterSale.getStatus()==5)
            {
                try {
                    Date time1 = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date time2 = sdf.parse(afterSale.getTime_out());
                    long time = time1.getTime() - time2.getTime();
                    if (time>1000*60*60*24*10){
                        afterSale.setStatus(6);
                        afterSaleMapper.updateAfterSaleStatus(afterSale);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public Result setAfterSaleStatus(String Token, String code, Integer status, String sql) {
        try {
            BsUser bsUser = (BsUser) redisTemplate.opsForValue().get(Token);
            afterSaleMapper.setAfterSaleStatus(code, status, sql, bsUser.getUsername());
            if (status == 4) {
                AfterSale afterSale = afterSaleMapper.getAfterSaleBycode(code);
                if (afterSale.getType() == 1) {
                    // 提醒退款审核
                    sendWxWorkUtil.sendAppoint(5);
                } else {
                    // 提醒补发
                    sendWxWorkUtil.sendAppoint(7);
                }
            } else if (status == 5) {
                // 提醒退款审核
                sendWxWorkUtil.sendAppoint(6);
            }
            return new Result(1, "SUCCESS", "", null);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(-1, "ERROR", "", null);
        }
    }

    @Override
    public Result setAfterSaleStatusTwo(String Token, String code, Integer statusTwo, String remark, String sql) {
        try {
            BsUser bsUser = (BsUser) redisTemplate.opsForValue().get(Token);
            afterSaleMapper.setAfterSaleStatusTwo(code, statusTwo, remark, sql, bsUser.getUsername());
            return new Result(1, "SUCCESS", "", null);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(-1, "ERROR", "", null);
        }
    }

    @Override
    public Result refundFlowFour(String Token, String code) {
        try {
            BsUser bsUser = (BsUser) redisTemplate.opsForValue().get(Token);
            if (bsUser == null) {
                return new Result(-1, "WARN", "操作无效", null);
            }

            AfterSale afterSale = afterSaleMapper.getAfterSaleBycode(code);

            int refundMethod = Integer.parseInt(afterSale.getRefund_method());
            if (refundMethod == 3) {
                // 处理线下汇款情况
                afterSaleMapper.setAfterSaleStatus(code, afterSale.getType() == 3 ? 4 : 6, ",flow_four = ", bsUser.getUsername());
                return new Result(1, "SUCCESS", "...", null);
            }

            Trade trade = afterSaleMapper.getPayTradeByAfter(afterSale.getOrder_code());

            if (trade == null) {
                return new Result(-1, "WARN", "操作失败，未查询到支付记录", null);
            }

            /*return switch (refundMethod) {
                case 1 -> { // 微信
                    BigDecimal amountInCents = trade.getTrade_amount().multiply(new BigDecimal(100));
                    Long new_type_amount = amountInCents.longValue();
                    AmountReq amount = new AmountReq();
                    amount.setRefund(new_type_amount);
                    amount.setTotal(new_type_amount);
                    amount.setCurrency("CNY");
                    yield payRefundUtil.weChatRefund(trade.getTrade_no(), afterSale.getOrder_code(), afterSale.getCode(), amount, bsUser.getUsername());
                }
                case 2 -> // 支付宝
                        payRefundUtil.alipayRefund(trade.getTrade_no(), afterSale.getRefund_amount().toString(), afterSale.getCode(), bsUser.getUsername());
                default -> new Result(-1, "WARN", "操作无效", null);
            };*/

            switch (refundMethod) {
                case 1:
                    BigDecimal amountInCents = trade.getTrade_amount().multiply(new BigDecimal(100));
                    Long new_type_amount = amountInCents.longValue();
                    AmountReq amount = new AmountReq();
                    amount.setRefund(new_type_amount);
                    amount.setTotal(new_type_amount);
                    amount.setCurrency("CNY");
                    return payRefundUtil.weChatRefund(trade.getTrade_no(), afterSale.getOrder_code(), afterSale.getCode(), amount, bsUser.getUsername());
                case 2:
                    return payRefundUtil.alipayRefund(trade.getTrade_no(), afterSale.getRefund_amount().toString(), afterSale.getCode(), bsUser.getUsername());
                default:
                    return new Result(-1, "WARN", "操作无效", null);
            }


        } catch (Exception e) {
            // 记录异常日志
            // logger.error("An error occurred in refundFlowFour", e);
            e.printStackTrace();
            return new Result(-1, "ERROR", e.getMessage(), null);
        }
    }

    @Override
    public Result getOrderAddress(String orderCode) {
        try {
            Order order = afterSaleMapper.getOrderAddress(orderCode);
            HashMap<String, Object> resultMap = new HashMap<>();
            resultMap.put("recipients", order.getRecipients());
            resultMap.put("phone", order.getPhone());
            resultMap.put("address", order.getAddress());
            return new Result(1, "SUCCESS", "", resultMap);
        } catch (Exception e) {
            e.getMessage();
            return new Result(-1, "ERROR", e.getMessage(), null);
        }
    }

    @Override
    public Result enterReissue(String code, String trackingCode) {
        try {
            afterSaleMapper.enterReissue(code, trackingCode);
            return new Result(1, "SUCCESS", "", null);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(-1, "ERROR", "", null);
        }
    }

    // @Override
    public Result refundFlowFourQY(String Token, String code) {
        try {
            BsUser bsUser = (BsUser) redisTemplate.opsForValue().get(Token);

            // 查询售后单
            AfterSale afterSale = afterSaleMapper.getAfterSaleBycode(code);
            if (afterSale.getStatus() < 5) {
                return new Result(1, "WARN", "操作无效", null);
            }
            // 查询支付记录
            Trade trade = afterSaleMapper.getPayTradeByAfter(afterSale.getOrder_code());
            if (trade == null) {
                return new Result(1, "WARN", "操作失败，未查询到支付记录", null);
            }
            if (trade.getTrade_platform() == 1) {
                // 微信
                // 退款金额信息
                BigDecimal amountInCents = trade.getTrade_amount().multiply(new BigDecimal(100));
                Long new_type_amount = amountInCents.longValue();
                AmountReq amount = new AmountReq();
                amount.setRefund(new_type_amount);
                amount.setTotal(new_type_amount);
                amount.setCurrency("CNY");
                return payRefundUtil.weChatRefund(trade.getTrade_no(), afterSale.getOrder_code(), afterSale.getCode(), amount, bsUser.getUsername());
            } else if (trade.getTrade_platform() == 2) {
                // 支付宝
                return payRefundUtil.alipayRefund(trade.getTrade_no(), afterSale.getRefund_amount().toString(), afterSale.getCode(), bsUser.getUsername());
            } else if (trade.getTrade_platform() == 3) {
                // 线下汇款
                afterSaleMapper.setAfterSaleStatus(code, 7, ",flow_four = ", bsUser.getUsername());
                return new Result(1, "WARN", "...", null);
            } else {
                return new Result(1, "WARN", "操作无效", null);
            }
        } catch (Exception e) {
            return new Result(-1, "ERROR", e.getMessage(), null);
        }
    }

    public List<AfterSale> AfterSaleData(List<AfterSale> afterSaleList) {
        for (AfterSale afterSale : afterSaleList) {
            System.out.println(afterSale.getCode());
            List<OrderAttachment> parts = afterSaleMapper.getAfterParts(afterSale.getCode(), afterSale.getOrder_code());
            afterSale.setOrderAttachmentList(parts);
        }
        String path = afterSaleMapper.getAfterBeforePath();
        afterSaleList.forEach(afterSale -> {
            for (char c = 'a'; c <= 'e'; c++) {
                String getterName = "getImg_" + c;
                String setterName = "setImg_" + c;
                try {
                    // 使用反射获取属性值
                    String propertyValue = (String) AfterSale.class.getMethod(getterName).invoke(afterSale);
                    if (!Objects.equals("", propertyValue)) {
                        // 使用反射设置属性值
                        AfterSale.class.getMethod(setterName, String.class).invoke(afterSale, path + propertyValue);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        return afterSaleList;
    }

    public List<Map<String, Object>> AfterSaleData2(List<Map<String, Object>> afterSaleList) {
        for (Map<String, Object> afterSaleMap : afterSaleList) {
            System.out.println(afterSaleMap.get("code"));
            List<OrderAttachment> parts = afterSaleMapper.getAfterParts(afterSaleMap.get("code").toString(), afterSaleMap.get("order_code").toString());
            afterSaleMap.put("part_list", parts);
        }
        String path = afterSaleMapper.getAfterBeforePath();
        afterSaleList.forEach(afterSale -> {
            for (char c = 'a'; c <= 'e'; c++) {
                String img_key = "img_" + c;
                String propertyValue = (String) afterSale.get(img_key);
                if (!Objects.equals("", propertyValue)) {
                    afterSale.put(img_key, path + propertyValue);
                }
            }
        });
        return afterSaleList;
    }
}
